// Copyright (C) Kumo inc. and its affiliates.
// Author: Jeff.li lijippy@163.com
// All rights reserved.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
//


#include "url_functions.h"
#include <optional>
#include <pollux/type/type.h>

namespace kumo::pollux::functions::detail {
    std::optional<StringView> matchAuthorityAndPath(
        StringView authorityAndPath,
        boost::cmatch &authorityMatch,
        int subGroup) {
        boost::cmatch authAndPathMatch;
        static const boost::regex kAuthorityAndPathRegex("//([^/]*)(/.*)?");
        if (!boost::regex_match(
            authorityAndPath.begin(),
            authorityAndPath.end(),
            authAndPathMatch,
            kAuthorityAndPathRegex)) {
            // Does not start with //, doesn't have authority.
            return std::nullopt;
        }

        static const boost::regex kAuthorityRegex(
            "(?:([^@:]*)(?::([^@]*))?@)?" // username, password.
            "(\\[[^\\]]*\\]|[^\\[:]*)" // host (IP-literal (e.g. '['+IPv6+']',
            // dotted-IPv4, or named host).
            "(?::(\\d*))?"); // port.

        const auto authority = authAndPathMatch[1];
        if (!boost::regex_match(
            authority.first, authority.second, authorityMatch, kAuthorityRegex)) {
            return std::nullopt; // Invalid URI Authority.
        }

        if (authorityMatch[subGroup].matched) {
            return detail::submatch(authorityMatch, subGroup);
        }

        return std::nullopt;
    }
} // namespace kumo::pollux::functions::detail
